#include "lsp_client.h"
#include "headers_cpp.h"
#include <sstream>

string brute_force(int index, string hash);
string brute_force(string start, string end, string hash);

using namespace std;

int get_index(char c)
{
	char alphabet[26];
	for(int i = 0; i < 26; i++) alphabet[i] = 'a' + i;
	int set_size = sizeof(alphabet);
	
	for(int i = 0; i < set_size; i++)
		if(alphabet[i] == c) return i;
	return -1;
}

int main(int argc, char** argv) 
{
	srand(12345);

	if(argc != 2)
	{
		cout << "Not proper agruments." << endl;
		return 0;
	}
	//Parse Arguments
	string hostport = argv[1];
	int indexofcol = hostport.find_first_of(":",0);
	if(indexofcol == string::npos)
	{
		cout << "Not proper agruments." << endl;
		return 0;
	}
	string dest = hostport.substr(0,indexofcol);
	string port = hostport.substr(indexofcol+1,hostport.size()-indexofcol-1);

	//Setup lsp server
	lsp_client* lsp = lsp_client_create(dest.c_str(), atoi(port.c_str()));
	if(lsp == NULL)
	{
		cout << "Failure connecting to server." << endl;
		return 0;
	}

	//Send join request
	string join_request = "j";
	if(!lsp_client_write(lsp, (uint8_t*) join_request.c_str(), join_request.length()+1))
	{
		cout << "Failed to send join request." << endl;
		return 0;
	}

	//Main loop. Loop till lsp closes
	while(lsp != NULL)
	{
		//Read from server
		char* pld; pld = (char*) malloc(1024);
		int lth = lsp_client_read(lsp, (uint8_t*) pld);

		if(lth <= 0)
		{
			cout << "Failure while reading from LSP Server" << endl;
		}
		else
		{
			//Sanitize pld to convert to string
			if(pld[lth-1] != '\0' && lth < 1024)
			{
				pld[lth] = '\0';
			}
			string read = string(pld);

			//Get ready to teokenize s
			istringstream iss (read);
			string tok;
			iss >> tok;

			//Vars
			string hash;
			string lower;
			string upper;

			//Make sure it is a crack request
			if(tok[0] == 'c')
			{
				iss >> hash;
				iss >> lower;
				iss >> upper;

				cout << "Working on hash:" << endl << hash << endl;

				string pass = brute_force(lower, upper, hash);

				if(pass[0] != '!') //found
				{
					string to_send = "f ";
					to_send += pass;
					lsp_client_write(lsp, (uint8_t*) to_send.c_str(), to_send.length()+1);
				}
				else
				{
					string to_send = "x";
					lsp_client_write(lsp, (uint8_t*) to_send.c_str(), to_send.length()+1);
				}
			}
		}
	}

	cout << "Lost Connection." << endl;
	return 0;
}

